/*
 * Library for implementing top-level call control state machine
 */
#ifndef _CALLCTRL_H_
#define _CALLCTRL_H_

/*===========================================================================*/
/*==============  Includes  =================================================*/
/*===========================================================================*/

#include <config.h>
#include <dateTime.h>
#include <avmerrCode.h>
#include <lang.h>

/*===========================================================================*/
/*==============  Data Definitions/Structures ===============================*/
/*===========================================================================*/


// callCtrlAutoAnswerMode -- type of auto-answering done
enum callCtrlAutoAnswerMode {
    // CAUTION CAUTION CAUTION
    // Modification to this can potentially make all existing
    // databases obsolete and worse misleading!

    callCtrlAutoAnswerMode_eOff = 0,    // must be 0 for default
    /* Mode "Reject" will reject the call when trigger is reached.
     */
    callCtrlAutoAnswerMode_eReject = 1,    // reject call
    /* Mode "Forward" will forward call to a configured phone number
     * when trigger is reached.
     */
    callCtrlAutoAnswerMode_eForward = 2,  // forward call
    /* Mode "Answer" will connect call with full audio (as if user
     * had answered) when trigger is reached.
     */
    callCtrlAutoAnswerMode_eAnswer = 3, // connect call, w/ full audio
    /* Mode "Message" will connect call and play message to other party
     * when trigger is reached... optionally it may record a message
     * as well?
     */
    callCtrlAutoAnswerMode_eMessage = 4,  // answer call with recorded message

    /* Keep this last: */
    callCtrlAutoAnswerMode_NModes
};

// callCtrlAutoAnswerWhen -- situations where automated auto answering is done
enum callCtrlAutoAnswerWhen {
    // CAUTION CAUTION CAUTION
    // Modification to this can potentially make all existing
    // databases obsolete and worse misleading!
    callCtrlAutoAnswerWhen_eNever = 0,         // make this 0 for default!
    callCtrlAutoAnswerWhen_eAlways = 1,
    callCtrlAutoAnswerWhen_eIfBusy = 2,
    callCtrlAutoAnswerWhen_eIfNoAnswer = 3,
    callCtrlAutoAnswerWhen_eIfBusyOrNoAnswer = 4,
};


struct callCtrlAnswerConfig
{
    // CAUTION CAUTION CAUTION
    // Any modification to this struct can potentially make all existing
    // databases obsolete and worse misleading!
    // Generally it is safe to add to end... so long as zero is
    // a good default value.

    /*
    * Version for this structure -- MUST be first.
    * Changing this makes #define makes previous records safely invalid
    * (user will have to reconfigure however...)
    */
#define CALLCTRL_AUTOANSWER_CONFIG_VERSION       1
    unsigned Version;

    /* The overall auto-answering mode */
    int /* enum callCtrlAutoAnswerMode */ AutoAnswerMode;

    /* For each auto-answer mode, there is a set of parameters.
     * These are remembered even when not in use so that user may
     * quickly return to them.
     */
    struct
    {
        int /* enum callCtrlAutoAnswerWhen */ When;
        int TimeoutSet;   /* if nonzero, use TimeoutSeconds, else default */
        unsigned TimeoutSeconds;        /* trigger time for no-answer */
    } Reject;

    struct
    {
        int /* enum callCtrlAutoAnswerWhen */ When;
        int TimeoutSet;   /* if nonzero, use TimeoutSeconds, else default */
        unsigned TimeoutSeconds;        /* trigger time for no-answer */
        /* Phone number to forward to: */
        char PhoneNumber[CFG_PHONEBOOK_DIGIT_MAX];
    } Forward;

    struct
    {
        int /* enum callCtrlAutoAnswerWhen */ When;
        int TimeoutSet;   /* if nonzero, use TimeoutSeconds, else default */
        unsigned TimeoutSeconds;        /* trigger time for no-answer */
    } Answer;

    struct
    {
        int /* enum callCtrlAutoAnswerWhen */ When;
        int TimeoutSet;   /* if nonzero, use TimeoutSeconds, else default */
        unsigned TimeoutSeconds;        /* trigger time for no-answer */
        unsigned MessageId;     /* which message to play */
        unsigned RecordSeconds; /* record time limit, 0 = no recording */
    } Message;

};

typedef enum
{
    TYPE_CODEC_G711,
    TYPE_CODEC_G726,
    TYPE_CODEC_G729,
    TYPE_CODEC_ILBC
} ZCOM_CODEC_TYPE;

#define MAX_ZCOM_CODEC_NUM  4

// callCtrlVoipConfig -- used to retrieve or set configuration to use
struct callCtrlVoipConfig {
    /*
     * CAUTION: changes to this structure can break the ui wlan
     * profile storage in flash (profiles 1 to 8);
     * really ui should be fixed, but....
     */

    /*
    * Version for this structure -- MUST be first.
    * Changing this makes #define makes previous records safely invalid
    * (user will have to reconfigure however...)
    */
#define CALL_VOIPCONFIG_VERSION       3
    unsigned Version;
    int isCurrent;

    /* Name -- for voip profile saving */
    char Name[CFG_VOIP_PROFILE_NAME_SZ];

    unsigned int Expire;

    /* Our phone number which we use to register ourselves with
    *   the sip registrar... null term. ascii text string.
    *   May be any null terminated string acceptable to voip stack
    *   and servers.
    */
    char OurPhoneNumber[CFG_PHONEBOOK_DIGIT_MAX];

    /* Enable high compression codecs (g729, g726)
    * (g711 alaw and ulaw are always enabled for now at least)
    */
    unsigned char EnableHighCompression;

    /* WAS: Acoustic echo cancellation enable.
    *   0 turns off echo cancellation.
    *   >= 1 enables echo cancellation.
    *   Values > 1 may have special meaning in future...
    *
    *   NOTE: this is no longer handled through the voip stack,
    *   except for being configured here... (NO LONGER)
    *   logically it belongs with audio hardware control, but
    *   people think of it as a voip thing because it becomes important
    *   for phone calls that have a lot of latency.
    */
    unsigned WAS_AcousticEchoCancelEnable;

    /*
    * SIP domain that our phone number belongs to.
    *   This also serves as default for sip server and proxy server.
    *   Optional append :port for nonstandard port.
    */
    char SipDomainNameString[CFG_NETWORK_SERVER_MAX];
    unsigned SipDomainPort;

    /*
    * SIP server that we talk to
    *   Optional append :port for nonstandard port.
    */
    char SipServerAddressString[CFG_NETWORK_SERVER_MAX];
    unsigned SipServerPort;

    /*
    * SIP Proxy that we talk to
    *   Optional append :port for nonstandard port.
    */
    char ProxyServerAddressString[CFG_NETWORK_SERVER_MAX];
    unsigned ProxyServerPort;

    /* SIP  authentication
     */
    char AuthenticationUserName[CFG_VOIP_PROXY_USER_MAX];
    char AuthenticationPassword[CFG_VOIP_PROXY_PASSWORD_MAX];

    /*
    * Stun Server
    *   Optional append :port for nonstandard port.
    */
    char StunServerAddressString[CFG_NETWORK_SERVER_MAX];
    unsigned StunServerPort;

    //
    // NAT keep alive time in seconds
    //
    unsigned int NATKeepAliveTime;

    //
    // Outbound Proxy Settings
    //
    char OutboundProxyServerAddressString[CFG_NETWORK_SERVER_MAX];
    unsigned OutboundProxyServerServerPort;

    //added by Mike for voip codec
    int vCodecs[MAX_ZCOM_CODEC_NUM]; //zcom codec in order (ZCOM_CODEC_TYPE)
    int nCurCodecs; //num of current used zcom codecs

    /*
    * Voice Mail Server that we talk to
    *   Optional append :port for nonstandard port.
    */
    char VoiceMailServerAddressString[CFG_NETWORK_SERVER_MAX];
    unsigned VoiceMailServerPort;

    /* Voice mail authentication
     */
    char VoiceMailUserName[CFG_VOIP_PROXY_USER_MAX];
    char VoiceMailPassword[CFG_VOIP_PROXY_PASSWORD_MAX];

    char DisplayName[CFG_VOIP_DISPLAY_NAME_MAX];
    struct callCtrlAnswerConfig AnswerConfig;

    //for call-id of privacy
	 //by Mike
	 int  bCallIDOff;

    bool bProfileEdited;
    bool bActive;        // for ZyXEL V630 Auto Provision
    bool bProvision;     // for ZyXEL V630 Auto Provision
};


typedef enum {
    callCtrlSignalTone_None = 0,          // no tone; must be zero
    callCtrlSignalTone_DialTone = 1,
    callCtrlSignalTone_RingTone = 2,
    callCtrlSignalTone_BusyTone = 3,
    callCtrlSignalTone_ErrorTone = 4
} callCtrlSignalToneType;


typedef struct callCtrlCallInfoStruct {
    /*
     * Current state of this call
     */
    enum callCtrlCallState {
        CC_CALLINFO_NOTUSED         = 0,        // no call happening
        CC_CALLINFO_OUTBOUND_ALERT  = 1,     // when we begin calling out
        CC_CALLINFO_INBOUND_ALERT   = 2,        // when we get inbound call
        CC_CALLINFO_ACTIVE          = 3,    // call+audio connection in place
        CC_CALLINFO_DISPLAYED       = 4,    // ... + acknowledged by ui
        CC_CALLINFO_ZOMBIE          = 5,    // waiting for ui to free us
    } state;

    /*
     * Our call index (index in CallInfo[] for debugging purposes)
     */
    unsigned idx;

    /* Our call sequence number (used for AVMI).
     * For outgoing calls, this should be a non-negative number assigned
     * by host (or assigned by callCtrl if host uses 0).
     * For incoming calls, this is a negative number assigned by callCtrl
     */
    int SequenceNumber;

    unsigned char outgoing;              /* 0=incoming, 1=outgoing */
    unsigned char ringing; /* only if outgoing+state=alert: 1=otherside is ringing */
    unsigned char muteOn;               /* 0=unmuted, 1=muted */
    unsigned char holdOn;               /* 0=no hold, 1=call is on hold by us*/
    unsigned char remoteHoldOn;         /* 0=no hold, 1=call on hold remotely*/
    unsigned char transferOn;           /* 0=not, 1=call being transferred */
    unsigned char conferenced;          /* 0=not, 1=in conference call */
    avmerrCode LastErrCode;

    /* TODO: need more sophisticated conferencing scheme.... or do we
     * want to restrict to just one conference?
     */

    /*
     * protocol stack index for this call (or ~0 if not known, at least for hs)
     */
    unsigned stackCallId;

    /*
     * When this call started (from initiation/alerting)
     */
    DateTimeSec alertStartTime;

    /*
     * When this call connected
     */
    DateTimeSec activeStartTime;
    unsigned    activeStartTimeRV;

    /*
     * Remote phone number
     */
    char phoneNum[CFG_PHONEBOOK_DIGIT_MAX];

    /*
     * Reverse lookup of phone number from phone book,
     * and various attributes according to who is calling us.
     * THIS IS USED BY ui ONLY...
     */
    unsigned PhoneNameMajorId;
    unsigned PhoneNameMinorId;

    /* Values for Vibrate (compatible with uiPhoneNameFlashRecord usage):
    *       0 = default,
    *       1 = do vibrate
    *       2 = do >not< vibrate
    */
    unsigned Vibrate;    /* should we use vibrator for incoming? */
    unsigned RingToneId;   /* what ring tone we should be using for incoming*/

    /*
     * Call protocol stack handle for this call
     */
    void *protocolHandle;

    /*
    * display name for incoming call, as given by caller.
    */
    char displayName[CFG_PHONEBOOK_NAME_SZ];

    /*
     * Phone number that we are transferring to (if we are)...
     * empty if we are not.
     */
    char TransferPhoneNumber[CFG_URI_MAX];

    //for peer to peer
    //added by Mike
    int useP2P;
    char hostIP[CFG_NETWORK_SERVER_MAX];
    unsigned hostPort;
} CallCtrlCallInfo;


/*===========================================================================*/
/*==============  Function prototypes =======================================*/
/*===========================================================================*/
// Tianjun, 2007-8-27 8:39:50
//  For UI Call Settings
void callCtrlSetCallerIDConfig(int bCallerIDOff);

//  For UI Call Settings
void callCtrlSetAnswerConfig(const struct callCtrlAnswerConfig *AnswerConfigP);

/*
 * Set a call to the active state
 */
extern void callCtrlActivateCall(CallCtrlCallInfo *call);

/*
 * Set a call to error state
 */
extern void callCtrlBadCall(CallCtrlCallInfo *call);

/*
 * Start, continue or stop an alert.  This is either an incoming call
 * ring or a ring-back tone for an outbound call.
 *
 * This gets called each time a call enters/leaves the alert
 * state, and each time the audio path is enabled/disabled.
 *
 * For an inbound call alert we make the phone ring by:
 *
 *   - if the audio path is off (ie: no active calls or all calls
 *     on hold), turn on the audio speaker, play a melody and issue
 *     a vibrate if present/enabled, or
 *
 *   - if the audio path is on (ie: active call not on hold), play
 *     a short tone in the audio path so the user can hear it
 *
 *   - we might have to switch between these modes if the active
 *     call stops or goes on/off hold
 *
 * For an outbound call we deliver the current ring-back tone
 * (eg: busy, rining, etc) to the local user.
 *
 * Also, there could be multiple alerts.  We just process the earliest
 * one.  Once it is answered or rejected then we check the others and
 * restart the alert if necessary.
 */
extern void callCtrlAlertUpdate(CallCtrlCallInfo *call);

/*
 * Remove a call from a conference.
 * No affect if the call is not conferenced.
 * If the conference would have only one call in it, the conference
 * is terminated.
 * The calls remain as independent calls.
 */
void callCtrlDeConference(
        CallCtrlCallInfo *call          /* call to remove from conference */
    );

/*
 * Remove a call from a conference.
 * No affect if the call is not conferenced.
 * If the conference would have only one call in it, the conference
 * is terminated.
 * The calls remain as independent calls.
 */
avmerrCode callCtrlDeConferenceBySlot(
        int callIdx,
        int SequenceNumber      /* 0=don't care, else check for match */
    );

/*
 * Kill a call, initiated by the local user.
 * The call goes to ZOMBIE state which should be later ack'd by ui.
 */
void callCtrlKill( CallCtrlCallInfo *call );

/*
 * Free up the call slot... call from ui only on reaching ZOMBIE state.
 */
void callCtrlFree( CallCtrlCallInfo *call );

/*
 * Put an active call on/off hold, initiated by the local user
 * Returns nonzero if fails.
 */
extern int callCtrlHoldSet(
        CallCtrlCallInfo *call,
        int hold               /* new value of hold on/off */
);

/*
 * Put all calls on hold.
 */
int callCtrlHoldAll(void);

//--- callCtrlStackHoldLocal -- internal callCtrl use only
void callCtrlStackHoldLocal(
        unsigned stackCallId,
        int hold
        );

//--- callCtrlStackHoldRemote -- internal callCtrl use only
void callCtrlStackHoldRemote(
        unsigned stackCallId,
        int hold
        );

/*
 * Put a call on/off mute, initiated by the local user
 * Returns nonzero if failed.
 */
extern int callCtrlMuteSet(
        CallCtrlCallInfo *call,
        int mute               /* new value of mute on/off */
        );

/*
 * Returns nonzero if callCtrlConference() would fail.
 */
avmerrCode callCtrlConferencePossible(void);

/*
 * Connect all (two) calls into a conference.
 * Currently UI and h.s. stack supports only max two calls so we can ignore
 * issue e.g. connecting > 2 users in conference call.
 * Returns nonzero in case of failure.
 * A current side effect is that, in case of failure, the first call
 * may have been taken off of hold (if on hold) and the second call
 * put on hold (if off of hold).
 */
extern avmerrCode callCtrlConference( void );

//--- callCtrlConferenceStarted -- callCtrl internal use only
void callCtrlConferenceStarted(void);

/*
 * Local user pressed a numeric key, so need to generate dtmf tones
 *
 * We generate a local dtmf tone to the speaker/receiver for feedback.
 *
 * TODO: For the network side do we send a message or a tone?
 */
extern void callCtrlLocalDTMFStart(CallCtrlCallInfo *call, int dtmfLow, int dtmfHigh);

/*
 * Local user released a numeric key, so stop dtmf tones
 */
extern void callCtrlLocalDTMFStop(CallCtrlCallInfo *call);

//for Peer to Peer mode
//added by Mike
extern avmerrCode callCtrlNewP2POutboundCall(
        const char *phoneNum,           // input
        const char *szIP,               // input
        unsigned  port,                 // input
        CallCtrlCallInfo **callPP       // output -- NULL or call handle
        );
extern void callCtrlSetP2PMode(bool useP2P);
extern bool callCtrlGetP2PMode();
extern void callCtrlSetHostIP(char * ip);
extern char * callCtrlGetHostIP();
extern void callCtrlSetHostPort(unsigned port);
extern unsigned callCtrlGetHostPort();
//for extension..
extern void callCtrlSetLocalPort(unsigned port);
extern unsigned callCtrlGetLocalPort();
//for NATs
extern unsigned callCtrlGetNATMapIP();
extern void callCtrlSetNATMapIP(unsigned addr);
extern unsigned callCtrlGetNATMapPort();
extern void callCtrlSetNATMapPort(unsigned port);

/*
 * Initiate a new outbound call to the given number.  This is
 * typically initiated by the user via the UI.
 * To have greater assurance of success, call
 * callCtrlNewOutboundPossibleCheck() before calling this.
 *
 * Returns with *callPP set to the new call pointer, or NULL on error.
 * Returns 0 for success, or else avmerrCode.
 */
extern avmerrCode callCtrlNewOutboundCall(
        const char *phoneNum,           // input
        CallCtrlCallInfo **callPP,      // output -- NULL or call handle
        int SequenceNumber              // 0 or seq. no. to use, > 0
        );

// callCtrlDtmfSend -- send dtmf digits in packetized form to current call.
int callCtrlDtmfSend(
    int digit           /* ascii char '0' to '9' or '*' or '#' */
    );
/*
 * Here when the other side is ringing the user (i.e. outgoing call)
 */
extern void callCtrlOutboundCallRinging(unsigned stackCallId);

//--- callCtrlOutboundCallAccepted -- callCtrl internal use only
extern void callCtrlOutboundCallAccepted(unsigned stackCallId);

//--- callCtrlCallRejected -- callCtrl internal use only
extern void callCtrlCallRejected(unsigned stackCallId, avmerrCode err);

//--- callCtrlRegistrationFailure -- callCtrl internal use only
void callCtrlRegistrationHandler(
        avmerrCode err,
        int expireTime /* seconds */
        );

//--- callCtrlOutboundCallAnswered -- callCtrl internal use only
void callCtrlOutboundCallAnswered(unsigned stackCallId);

//--- callCtrlSubscribeMwiHandler -- callCtrl internal use only
void callCtrlSubscribeMwiHandler(
            avmerrCode err,
            unsigned expireSeconds
            );

//--- callCtrlVoiceMailWaiting -- callCtrl internal use only
void callCtrlVoiceMailWaitingSet(
    int NNewMsgs,
    int NOldMsgs,
    int NNewUrgentMsgs,
    int NOldUrgentMsgs
    );

// Called from application to poll voice mail waiting status
void callCtrlVoiceMailWaitingGet(
    int *NNewMsgsP,             /* NULL or output */
    int *NOldMsgsP,             /* NULL or output */
    int *NNewUrgentMsgsP,       /* NULL or output */
    int *NOldUrgentMsgsP        /* NULL or output */
    );

/*
 * Handle a new inbound call.  This is typically initiated by
 * a remote caller via the call protocol stack.
 * callCtrl internal use only.
 *
 * Returns the new call, or NULL on error.
 */
extern CallCtrlCallInfo *callCtrlNewInboundCall(
        const char *fromPhoneNum,
        const char *fromDisplayName,
        unsigned stackCallId);

/*
 * Handle a replaced call.  for attended transfer.
 * callCtrl internal use only.
 *
 * Returns the new call, or NULL on error.
 */
extern CallCtrlCallInfo *callCtrlReplaceCall(
        const char *fromPhoneNum,
        const char *fromDisplayName,
        unsigned stackCallId,
        unsigned stackCallIdNew);

/*
 * Acknowledge that the call has gone active.
 * Called by ui when it finds (by polling) any new calls that have become active
 * including those outbound calls.
 */
extern void callCtrlCallIsDisplayed(CallCtrlCallInfo *call);

// callCtrlHandoffCall -- attempt to join two calls, minus us.
int callCtrlHandoffCall( void );

/* callCtrlTransferCall -- attempt to forward a call.
 *     If there is an immediate nonzero return, then the call is entirely
 *     unaffected.
 *     Otherwise, the call will either be forwarded and terminated,
 *     or %%%%%%%%% ?
 *     The call is automatically put on hold while being transferred.
 */
int callCtrlTransferCall(
        CallCtrlCallInfo *call,         // call to forward
        const char *phoneNum            // phone no. to forward to
        );

//---- callCtrlTransferDone -- callCtrl internal use only
void callCtrlTransferDone(
        unsigned stackCallId,
        int fail                        // nonzero if failed
        );

void callCtrlStackTransferCall(
        unsigned stackCallId
        );

void callCtrlCheckForNewOutboundCall(
        void
        );

void callCtrlStackCallTransfered(
        unsigned stackCallId,
        unsigned stackCallIdNew,
        const char *uri,
        const char *display_name
        );

void callCtrlStackForwardCall(
        unsigned stackCallId,
        const char *uri,
        const char *display_name
        );

/*
 * Find a call for the given slot.
 * Returns NULL if invalid slot.
 */
extern CallCtrlCallInfo *callCtrlFindCallBySlot(
        int Slot        /* 0 to CFG_CALL_MAX-1 */
        );

/*
 * Find a call in given state, or NULL if none.
 * Call repeatedly to find all in given state provided that you change
 * the state of each one found.
 */
extern CallCtrlCallInfo *callCtrlFindCallByState(
        enum callCtrlCallState state
        );

/* callCtrlCheckConfig -- returns nonzero if not sufficiently configured.
*/
extern int callCtrlCheckConfig(void);

/* callCtrlCheckResolve -- returns nonzero if not sufficiently resolved.
*/
extern avmerrCode callCtrlCheckResolve(void);

/*
 * Returns 0 if it is possible to make a new outbound call,
 * else returns language specific error code for display.
 * No new outbound calls may be made while one is pending or
 * if there are too many already, or if the system is not configured
 * or is not otherwise ready.
 */
//only called for SIP Proxy call-check only
//by Mike
extern avmerrCode callCtrlNewOutboundPossibleCheck(void);

//for call-id
extern int callCtrlGetOwnerShown();
extern void callCtrlSetOwnerShown(int show);

unsigned int callCtrlGetExpire();

/* Return our phone number for display use and use w/ voip stack
 */
extern const char *callCtrlGetOurPhoneNumber(void);

// callCtrlInit -- Call during initialization.
//      Normally is called from ui task, thus the name uiUpdate...
//      however, uiUpdate may be passed as NULL in which
//      case no update function is called.
//      In case of redundant calls, the last non-NULL value for uiUpdate wins.
//      The update function must return quickly; should just
//      schedule a few things.
extern void callCtrlInit(void (*uiUpdate)(void));

/*
 * callCtrlAudioChangeCallbackInstall -- install callback that
 * is called with new audio state whenever it changes.
 * The audio state is on whenever we have calls up that can use audio,
 * even if muted, and off otherwise.
 */
void callCtrlAudioChangeCallbackInstall(
    void (*AudioChangeCB)(int AudioOn)  // callback on audio state change
    );

extern void callCtrlStop(void);

// callCtrlSipServerGet -- get ip address (host order) of sip server (or zero).
//      This is for ui/diagnostic purposes...
unsigned callCtrlSipServerGet(void);

// callCtrlProxyServerGet -- get ip address (host order) of proxy server (or zero).
//      This is for ui/diagnostic purposes...
unsigned callCtrlProxyServerGet(void);

// callCtrlStunServerGet -- get ip address (host order) of STUN server (or zero).
//      This is for ui/diagnostic purposes...
unsigned callCtrlStunServerGet(void);

// callCtrlOutboundProxyServerGet -- get ip address (host order) of OutboundProxy server (or zero).
//      This is for ui/diagnostic purposes...
unsigned callCtrlOutboundProxyServerGet(void);

// callCtrlVoipConfigGet -- get copy of current configuration
void callCtrlVoipConfigGet(
        struct callCtrlVoipConfig *ConfigP      // output
        );

// callCtrlVoipConfigDefaultGet -- get default values
//      only for those fields which clearly have a wrong value.
//      Clear *ConfigP before calling to get all defaults.
void callCtrlVoipConfigDefaultGet(
        struct callCtrlVoipConfig *ConfigP      // output
        );

// callCtrlVoipConfigSet -- set new configuration.
//      This causes the voip interface to be taken down
//      while the new configuration is being put in place.
//      If passed NULL argument, the voip stack is simply cycled
void callCtrlVoipConfigSet(
        const struct callCtrlVoipConfig *ConfigP
        );

/* returns nonzero if registration failed */
avmerrCode callCtrlRegstrationStatusGet( void );

/* callCtrlAnswerConfigGet -- return address of auto-answer
 * configuration parameters.
 * Changes can be made through the pointer but must be quickly flushed
 * by calling callCtrlAnswerConfigFlush().
 */
struct callCtrlAnswerConfig *callCtrlAnswerConfigGet(void);

/* callCtrlAnswerConfigFlush -- cause changes to AnswerConfig to
 * be propogated.
 */
//void callCtrlAnswerConfigFlush(void);

/*=========================================================================*/
/*========   avmi compatible ==============================================*/
/*=========================================================================*/

/*
 * Initiate a new outbound call to the given number using given slot.
 * Returns 0 for success, or else avmerrCode.
 */
avmerrCode callCtrlNewOutboundCallBySlot(
        const char *phoneNum,           // input
        int callIdx,                    // which call slot (0 or 1)
        int SequenceNumber              // 0 or seq. no. to use, > 0
        );

/* Accept a call that is incoming on given slot */
avmerrCode callCtrlAcceptCallBySlot(
        int callIdx,                    // which call slot (0 or 1)
        int SequenceNumber      // 0 or must match call
        );

/* Cancel any call that is on given slot */
avmerrCode callCtrlCancelCallBySlot(
        int callIdx,                    // which call slot (0 or 1)
        int SequenceNumber      // 0 or must match call
        );

/* Hold a call that is on given slot */
avmerrCode callCtrlHoldCallBySlot(
        int callIdx,                    // which call slot (0 or 1)
        int SequenceNumber,     // 0 or must match call
        int HoldOn
        );

/* Mute a call that is on given slot */
avmerrCode callCtrlMuteCallBySlot(
        int callIdx,                    // which call slot (0 or 1)
        int SequenceNumber,     // 0 or must match call
        int MuteOn
        );

avmerrCode callCtrlTransferCallBySlot(
        int callIdx,            // which call slot (0 or 1) we transfer
        int SequenceNumber,     // 0 or must match call
        const char *phoneNum            // input, phone num.
        );

avmerrCode callCtrlHandoffCallBySlot(
        int callIdx1,           // which call slot (0 or 1) we join
        int SequenceNumber1,    // 0 or must match call
        int callIdx2,           // which call slot (0 or 1) we join
        int SequenceNumber2     // 0 or must match call
        );

avmerrCode callCtrlConferenceBySlot(
        int WhichCall1,         /* active, unheld call */
        int SequenceNumber1,    /* 0 or must match that of call1 */
        int WhichCall2,         /* active but held call */
        int SequenceNumber2     /* 0 or must match that of call2 */
        );

int zcom_callCtrlHaveIncomingOrOutgoingCall();

void callCtrl_ResetFactory(void);

void callCtrlVoipConfigSetDefault(
        struct callCtrlVoipConfig *ConfigP      // output
        );

///////////////////////////////
// for new register scheme
// by Mike
//

//API for register manager
enum _regNotifyState
{
   _REG_NOTIFY_STATE_STOP,
   _REG_NOTIFY_STATE_RUNNING,
   _REG_NOTIFY_STATE_REGISTERED
} E_REG_NOTIFYSTATE;

bool callCtrlCanRegister();
int callCtrlGetRegisterNotifyState(); //ret E_REG_NOTIFY
unsigned callCtrlGetRegExpires();
void callCtrlClearRegister(bool stop);

//API for IM
//by Mike
bool callCtrlReceiveIM(char * caller, char * msg);
bool callCtrlCansendIM();
bool callCtrlSendIM(char * number, char * msg);
//reserved
//bool callCtrlSendIM(char * number, char * domain, unsigned port, char * msg);
extern void callCtrlVoipRegisterTaskStart(); //2007-12-11 16:13:44
/*=========================================================================*/
/*========   End        ===================================================*/
/*=========================================================================*/

#endif /* _CALLCTRL_H_ */
